package com.yuan.java.socket.niosocket;

import org.junit.Test;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

/**
 * nio 三个 重要的类  buffer , channel, selector
 * 接收数据  channel  -> buffer
 * 接收完毕后 读取数据  buffer -> channel
 */

public class Server {

    @Test
    public void main() throws Exception {
        //创建socketChannel
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //绑定端口
        ssc.socket().bind(new InetSocketAddress(8080));
        //配置为非阻塞模式
        ssc.configureBlocking(false);
        Selector selector = Selector.open();
        //注册selector
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            //等待连接
            if (selector.select(3000) == 0) {
                continue;
            }
            //已经有 连接 处理请求
            selector.selectedKeys().forEach(selectionKey -> {
                try {
                    if (selectionKey.isAcceptable()) {
                        //写入 缓冲区数据
                        SocketChannel sc = ((ServerSocketChannel) selectionKey.channel()).accept();
                        sc.configureBlocking(false);
                        sc.register(selectionKey.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                    }
                    if (selectionKey.isReadable()) {
                        //读取缓冲区数据
                        SocketChannel sc = (SocketChannel) selectionKey.channel();
                        ByteBuffer buffer = (ByteBuffer) selectionKey.attachment();
                        buffer.clear();
                        if (sc.read(buffer) == -1) {
                            sc.close();
                        } else {
                            //把 读 模式转换成 写模式
                            buffer.flip();
                            String receivedString = Charset.forName("UTF-8").newDecoder().decode(buffer).toString();
                            System.out.println("received from client" + receivedString);
                            String sendString = "received data :" + receivedString;
                            buffer = ByteBuffer.wrap(sendString.getBytes("UTF-8"));
                            sc.write(buffer);
                            sc.close();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            //清空本次的 连接
            selector.selectedKeys().clear();
        }
    }

}
